﻿
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Drawing.Imaging;
    using System.IO;
    using AForge.Imaging;
    using AForge;
    using AForge.Math.Geometry;
    using AForge.Imaging.Filters;
    using Bildverarbeitung;

namespace Bildverarbeitung.CGFilter
{
    public class KellerChristopher : Bildverarbeitung.IFilter
    {
        //Methode, die den Namen des Authors liefert.
        public String GetName()
        {
            return ("KellerChristopher");
        }
        //Filter für Durchschnittsbild
        public Bitmap GetImageWithDoor(Bitmap initialimage)
        {
            if (initialimage != null)
            {
                //Initialisierung der benötigten Variablen
                AForge.Imaging.Filters.SobelEdgeDetector edgeFilter;
                Bitmap filteredimage;
                Bitmap readimage;
                SaturationCorrection sfilter = new SaturationCorrection(-0.8f);
                Pen rot = new Pen(Color.Red, 4);
                Pen gruen = new Pen(Color.Green, 4);
              


                readimage = AForge.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(initialimage);
                edgeFilter = new AForge.Imaging.Filters.SobelEdgeDetector();
                edgeFilter.ApplyInPlace(readimage);
                filteredimage = readimage.Clone(new Rectangle(0, 0, readimage.Width, readimage.Height), PixelFormat.Format24bppRgb);
                List<List<IntPoint>> rectangles = shapeChecker(filteredimage);

                
                filteredimage = initialimage;
                sfilter.ApplyInPlace(filteredimage);

                List<IntPoint> biggestRectangleCorners = null;
                float biggestRectangleArea = 0;
                Graphics grafikscene = Graphics.FromImage(filteredimage);
               
                foreach (List<IntPoint> eckpunkte in rectangles)
                {
                    if (eckpunkte.Count == 4)
                    { 
                        if (calcPolygonArea(eckpunkte) > biggestRectangleArea)
                        {
                            biggestRectangleArea = calcPolygonArea(eckpunkte);
                            biggestRectangleCorners = eckpunkte;
                        }
                        foreach (IntPoint point in eckpunkte)
                        {
                            grafikscene.DrawRectangle(rot, point.X - 2, point.Y - 2, 5, 5);
                        }
                       
                        grafikscene.DrawPolygon(gruen, ToPointsArray(eckpunkte));
                    }
                }

               
                if (biggestRectangleCorners != null)
                {
                    SolidBrush yellowBrush = new SolidBrush(Color.Yellow);
                    grafikscene.FillPolygon(yellowBrush, ToPointsArray(biggestRectangleCorners));
                    yellowBrush.Dispose();
                }

                gruen.Dispose();
                rot.Dispose();
                grafikscene.Dispose();

             
                return filteredimage;
            }
            return null;
        }
        private float calcPolygonArea(List<IntPoint> corners)
        {
            float area = 0;
            int counter;

            for (int i = 0; i < corners.Count; i++)
            {
                counter = (i + 1) % (corners.Count);
                area += (corners[i].Y + corners[counter].Y) * (corners[i].X - corners[counter].X);
            }
            return area / 2;
        }
        private List<List<IntPoint>> shapeChecker(Bitmap bitmap)
        {
            List<List<IntPoint>> rectangleCorners = new List<List<IntPoint>>();
            
            BitmapData imagebitmap = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);

            //Hintergrund Farbe ändern
            ColorFiltering cfilter = new ColorFiltering();
            cfilter.Red = new IntRange(0, 64);
            cfilter.Green = new IntRange(0, 64);
            cfilter.Blue = new IntRange(0, 64);
            cfilter.FillOutsideRange = false;
            cfilter.ApplyInPlace(imagebitmap);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 5;
            blobCounter.MinWidth = 5;
            blobCounter.ProcessImage(imagebitmap);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(imagebitmap);
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();


            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> corners;
                shapeChecker.IsConvexPolygon(edgePoints, out corners);
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
                        rectangleCorners.Add(corners);   
            }
            return rectangleCorners;
        }
        private System.Drawing.Point[] ToPointsArray(List<IntPoint> pointstodraw)
        {
            System.Drawing.Point[] drawingpoints = new System.Drawing.Point[pointstodraw.Count];

            for (int i = 0, n = pointstodraw.Count; i < n; i++)
            {
                drawingpoints[i] = new System.Drawing.Point(pointstodraw[i].X, pointstodraw[i].Y);
            }
            return drawingpoints;
        }
    }
}
